package com.whmall.service.crm.module.company.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.whmall.common.util.Wh;
import com.whmall.component.service.AbstractDbService;
import com.whmall.component.util.FieldUtils;
import com.whmall.service.crm.entity.dto.company.SupplierAccountKeyFieldRspDTO;
import com.whmall.service.crm.entity.dto.company.SupplierAccountQueryReqDTO;
import com.whmall.service.crm.module.company.dao.CompanyMapper;
import com.whmall.service.crm.module.company.dao.SupplierAccountMapper;
import com.whmall.service.crm.module.company.entity.CompanyDO;
import com.whmall.service.crm.module.company.entity.SupplierAccountDO;
import com.whmall.service.crm.module.company.entity.qo.SupplierAccountQO;
import com.whmall.service.crm.module.company.service.SupplierAccountService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@RequiredArgsConstructor
@Service
public class SupplierAccountServiceImpl extends AbstractDbService<SupplierAccountMapper, SupplierAccountDO> implements SupplierAccountService {

    private final SupplierAccountMapper supplierAccountMapper;
    private final CompanyMapper companyMapper;

    @Override
    public SupplierAccountKeyFieldRspDTO queryById(long id) {
        return BeanUtil.copyProperties(supplierAccountMapper.selectById(id), SupplierAccountKeyFieldRspDTO.class);
    }

    @Override
    public Map<Long, SupplierAccountKeyFieldRspDTO> queryByIds(List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return Collections.emptyMap();
        }
        return supplierAccountMapper.selectBy(SupplierAccountQO.builder().ids(ids).build())
                .stream().map(e -> {
                    SupplierAccountKeyFieldRspDTO rspDTO = new SupplierAccountKeyFieldRspDTO();
                    BeanUtils.copyProperties(e, rspDTO);
                    return rspDTO;
                }).collect(Collectors.toMap(SupplierAccountKeyFieldRspDTO::getId, e -> e));
    }

    @Override
    public Map<String, List<SupplierAccountKeyFieldRspDTO>> queryByAccounts(List<String> accounts) {
        if (CollectionUtils.isEmpty(accounts)) {
            return Collections.emptyMap();
        }
        return supplierAccountMapper.selectBy(SupplierAccountQO.builder()
                        .accounts(accounts.stream().distinct().collect(Collectors.toList()))
                        .isEnabled(1).deleted(0).build())
                .stream().map(e -> {
                    SupplierAccountKeyFieldRspDTO rspDTO = new SupplierAccountKeyFieldRspDTO();
                    BeanUtils.copyProperties(e, rspDTO);
                    return rspDTO;
                }).collect(Collectors.groupingBy(SupplierAccountKeyFieldRspDTO::getAccount, Collectors.toList()));
    }

    @Override
    public Map<String, List<SupplierAccountKeyFieldRspDTO>> queryByAccountNames(List<String> accountNames) {
        if (CollectionUtils.isEmpty(accountNames)) {
            return Collections.emptyMap();
        }
        List<SupplierAccountDO> supplierAccountDOS = supplierAccountMapper.selectBy(SupplierAccountQO.builder()
                .accountNames(accountNames.stream().distinct().collect(Collectors.toList()))
                .isEnabled(1).deleted(0).build());

        List<Long> companyIds = supplierAccountDOS.stream().map(SupplierAccountDO::getCompanyId).collect(Collectors.toList());
        Map<Long, CompanyDO> companyDOMap = companyMapper.getByIds(companyIds).stream().collect(Collectors.toMap(CompanyDO::getId, e -> e, (e1, e2) -> e2));

        return supplierAccountDOS.stream().map(e -> {
            SupplierAccountKeyFieldRspDTO rspDTO = new SupplierAccountKeyFieldRspDTO();
            BeanUtils.copyProperties(e, rspDTO);
            rspDTO.setAccountName(Wh.Str.toDbc(rspDTO.getAccountName()).trim());
            if (companyDOMap.containsKey(e.getCompanyId())) {
                rspDTO.setCompanyName(Wh.Str.toDbc(companyDOMap.get(e.getCompanyId()).getName()).trim());
            }
            return rspDTO;
        }).collect(Collectors.groupingBy(SupplierAccountKeyFieldRspDTO::getAccountName, Collectors.toList()));
    }

    @Override
    public Map<Long, List<SupplierAccountKeyFieldRspDTO>> queryByCompanyIds(List<Long> companyIds) {
        if (CollectionUtils.isEmpty(companyIds)) {
            return Collections.emptyMap();
        }
        return supplierAccountMapper.selectBy(SupplierAccountQO.builder()
                        .companyIds(companyIds.stream().distinct().collect(Collectors.toList()))
                        .isEnabled(1).deleted(0).build())
                .stream().map(e -> {
                    SupplierAccountKeyFieldRspDTO rspDTO = new SupplierAccountKeyFieldRspDTO();
                    BeanUtils.copyProperties(e, rspDTO);
                    return rspDTO;
                }).collect(Collectors.groupingBy(SupplierAccountKeyFieldRspDTO::getCompanyId, Collectors.toList()));
    }

    @Override
    public List<SupplierAccountKeyFieldRspDTO> queryBy(SupplierAccountQueryReqDTO queryReqDTO) {
        SupplierAccountQO qo = new SupplierAccountQO();
        BeanUtils.copyProperties(queryReqDTO, qo);
        qo.setDeleted(0);
        return supplierAccountMapper.selectBy(qo).stream().map(e -> {
            SupplierAccountKeyFieldRspDTO rspDTO = new SupplierAccountKeyFieldRspDTO();
            BeanUtils.copyProperties(e, rspDTO);
            rspDTO.setDefaultAccount(FieldUtils.unwrapDefault(e.getDefaultAccount()));
            return rspDTO;
        }).collect(Collectors.toList());
    }

    @Override
    public SupplierAccountKeyFieldRspDTO getDefaultAccount(Long companyId) {
        SupplierAccountDO account = supplierAccountMapper.selectOne(new LambdaQueryWrapper<SupplierAccountDO>()
                .eq(SupplierAccountDO::getDeleted, 0)
                .eq(SupplierAccountDO::getCompanyId, companyId)
                .eq(SupplierAccountDO::getDefaultAccount, 1));
        if (account == null) {
            return null;
        }
        SupplierAccountKeyFieldRspDTO rspDTO = new SupplierAccountKeyFieldRspDTO();
        BeanUtils.copyProperties(account, rspDTO);
        rspDTO.setDefaultAccount(FieldUtils.unwrapDefault(account.getDefaultAccount()));
        return rspDTO;
    }
}
